<template>
  <div class="markdown-editor">
    <div class="editor-container" :class="{ 'preview-mode': previewMode }">
      <div class="editor-area" v-show="!previewMode">
        <textarea
          ref="textarea"
          v-model="content"
          @input="handleInput"
          @scroll="handleScroll"
          @keydown.tab.prevent="handleTab"
          placeholder="开始写作..."
        ></textarea>
      </div>
      <div 
        class="preview-area" 
        :class="{ 'full': previewMode }"
        ref="previewArea"
        v-html="renderedContent"
      ></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import { useSettingsStore } from '@/stores/settings'

const props = defineProps<{
  modelValue: string
  previewMode: boolean
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: string): void
  (e: 'save'): void
}>()

const settingsStore = useSettingsStore()
const textarea = ref<HTMLTextAreaElement>()
const previewArea = ref<HTMLDivElement>()
const content = ref(props.modelValue)
const scrollSync = ref(true)

// 配置 markdown-it
const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight: function (str, lang) {
    if (settingsStore.settings.editor.markdownConfig.codeHighlight && lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(str, { language: lang }).value
      } catch (__) {}
    }
    return '' // 使用外部的默认转义
  }
})

// 渲染 Markdown 内容
const renderedContent = computed(() => {
  return md.render(content.value || '')
})

// 监听内容变化
watch(() => props.modelValue, (newValue) => {
  if (newValue !== content.value) {
    content.value = newValue
  }
})

// 处理输入
const handleInput = () => {
  emit('update:modelValue', content.value)
}

// 处理滚动同步
const handleScroll = (e: Event) => {
  if (!scrollSync.value || !textarea.value || !previewArea.value) return
  
  const textareaEl = textarea.value
  const previewEl = previewArea.value
  const percentage = textareaEl.scrollTop / (textareaEl.scrollHeight - textareaEl.clientHeight)
  previewEl.scrollTop = percentage * (previewEl.scrollHeight - previewEl.clientHeight)
}

// 处理 Tab 键
const handleTab = (e: KeyboardEvent) => {
  if (!textarea.value) return
  
  const start = textarea.value.selectionStart
  const end = textarea.value.selectionEnd
  const spaces = '  '
  
  content.value = content.value.substring(0, start) + spaces + content.value.substring(end)
  
  nextTick(() => {
    if (textarea.value) {
      textarea.value.selectionStart = textarea.value.selectionEnd = start + 2
    }
  })
}
</script>

<style lang="scss" scoped>
.markdown-editor {
  height: 100%;
  
  .editor-container {
    height: 100%;
    display: flex;
    gap: 16px;
    
    &.preview-mode {
      .preview-area {
        flex: 1;
      }
    }
  }
  
  .editor-area {
    flex: 1;
    
    textarea {
      width: 100%;
      height: 100%;
      padding: 16px;
      border: none;
      outline: none;
      resize: none;
      background: transparent;
      color: var(--el-text-color-primary);
      font-size: 14px;
      line-height: 1.6;
      font-family: 'Fira Code', monospace;
    }
  }
  
  .preview-area {
    flex: 1;
    padding: 16px;
    overflow-y: auto;
    border-left: 1px solid var(--el-border-color-light);
    
    &.full {
      border-left: none;
    }
    
    :deep(h1, h2, h3, h4, h5, h6) {
      margin-top: 24px;
      margin-bottom: 16px;
      font-weight: 600;
      line-height: 1.25;
    }
    
    :deep(h1) {
      font-size: 2em;
      padding-bottom: 0.3em;
      border-bottom: 1px solid var(--el-border-color-light);
    }
    
    :deep(h2) {
      font-size: 1.5em;
      padding-bottom: 0.3em;
      border-bottom: 1px solid var(--el-border-color-light);
    }
    
    :deep(p) {
      margin-top: 0;
      margin-bottom: 16px;
    }
    
    :deep(blockquote) {
      margin: 0;
      padding: 0 1em;
      color: var(--el-text-color-regular);
      border-left: 0.25em solid var(--el-border-color);
    }
    
    :deep(ul, ol) {
      padding-left: 2em;
      margin-top: 0;
      margin-bottom: 16px;
    }
    
    :deep(code) {
      padding: 0.2em 0.4em;
      margin: 0;
      font-size: 85%;
      background-color: var(--el-fill-color-light);
      border-radius: 6px;
      font-family: 'Fira Code', monospace;
    }
    
    :deep(pre) {
      padding: 16px;
      overflow: auto;
      font-size: 85%;
      line-height: 1.45;
      background-color: var(--el-fill-color-light);
      border-radius: 6px;
      margin-bottom: 16px;
      
      code {
        padding: 0;
        margin: 0;
        background-color: transparent;
        border-radius: 0;
      }
    }
    
    :deep(table) {
      display: block;
      width: 100%;
      overflow: auto;
      margin-bottom: 16px;
      border-spacing: 0;
      border-collapse: collapse;
      
      th, td {
        padding: 6px 13px;
        border: 1px solid var(--el-border-color);
      }
      
      tr {
        background-color: var(--el-bg-color);
        border-top: 1px solid var(--el-border-color);
        
        &:nth-child(2n) {
          background-color: var(--el-fill-color-lighter);
        }
      }
    }
    
    :deep(img) {
      max-width: 100%;
      box-sizing: border-box;
    }
    
    :deep(hr) {
      height: 0.25em;
      padding: 0;
      margin: 24px 0;
      background-color: var(--el-border-color);
      border: 0;
    }
  }
}
</style>
